#pragma once
#include <semaphore.h>
#include <ctime>
#include <pthread.h>
class sem
{
public:
    sem() : _sem(new sem_t)
    {
        sem_init(_sem, PTHREAD_PROCESS_PRIVATE, 0);
    }

    sem(int value, int pshared = PTHREAD_PROCESS_PRIVATE) : _sem(new sem_t)
    {
        sem_init(_sem, pshared, value);
    }

    int wait()
    {
        return sem_wait(_sem);
    }

    int time_wait(const time_t &ms)
    {
        struct timespec countdown;
        clock_gettime(CLOCK_REALTIME, &countdown);
        countdown.tv_sec += ms / 1000;
        time_t micro_second = ms % 1000 * 1000;
        countdown.tv_sec += (micro_second + countdown.tv_nsec / 1000) / 1000000;
        countdown.tv_nsec = (micro_second * 1000 + countdown.tv_nsec) % 1000000000;

        return sem_timedwait(_sem, &countdown);
    }

    int try_wait()
    {
        return sem_trywait(_sem);
    }

    int post()
    {
        return sem_post(_sem);
    }

    ~sem()
    {
        sem_destroy(_sem);
        delete _sem;
    }

private:
    sem_t *_sem;
};